using System;
using System.Collections.Generic;
using DslCrossModelFramework;
using DslCrossModelFramework.Environment;
using DslCrossModelFramework.VSPackage;
using Microsoft.VisualStudio.Modeling;
using NMock2;

namespace UnitTest.xUnitTests.CrossModelFramework.Mocks {
    public class UnitTestEnvironmentConfiguration : IEnvironmentConfiguration {
        private IModelDirectory modelDirectory;
        private Transaction transaction;

        public UnitTestEnvironmentConfiguration() {
            //store.RuleManager.SuspendRuleNotification();
            //transaction = store.TransactionManager.BeginTransaction("DSL Integration");
        }

        public string Name {
            get { return "Unit Testing"; }
        }

        public bool IsActive {
            get { return true; }
        }

        public void InitializeEnvironment() {
            isInitialized = true;
        }

        public void ResetEnvironment() {
            this.modelDirectory = null;
            this.modelFiles = null;
            this.store = new Store();
            isInitialized = false;
        }

        public bool IsInitialized {
            get { return isInitialized; }
        }

        private bool isInitialized;

        public List<IModelFileInfo> ModelFiles {
            get {
                if(modelFiles == null) {
                    modelFiles=  new List<IModelFileInfo>();
                    Packages.ForEach(delegate(DslToolsPackageInfo packageInfo) { modelFiles.AddRange(GetModelFiles(packageInfo));});
                }
                return modelFiles;
            }
        }

        private List<IModelFileInfo> modelFiles;

        public List<DslToolsPackageInfo> Packages {
            get { if(packages == null) {
                packages = GetExportablePackages();
            }
                return packages;
            }
        }

        private List<DslToolsPackageInfo> packages;

        public List<DslToolsPackageInfo> GetExportablePackages() {
            return TestHelper.GetPackages();
        }

        public List<IModelFileInfo> GetModelFiles(DslToolsPackageInfo packageInfo) {
            List<IModelFile> retrievedModelFiles = TestHelper.GetModels();
            List<IModelFileInfo> foundInfos = new List<IModelFileInfo>();
            retrievedModelFiles.ForEach(delegate(IModelFile file) {
                                            IModelFileInfo fileInfo =
                                                new ModelFileInfo(file, packageInfo,
                                                                  this.GetModelDirectory() as ModelDirectory, store);
                                            fileInfo.Loaded += new EventHandler<ModelFileEventArgs>(fileInfo_Loaded);
                                            fileInfo.Unloaded += new EventHandler<ModelFileEventArgs>(fileInfo_Unloaded);
                                            if(this.ModelFileAdded != null){ModelFileAdded(this, new ModelFileEventArgs(fileInfo));}
                                            foundInfos.Add(fileInfo);
                                        });
            return foundInfos;
        }

        void fileInfo_Unloaded(object sender, ModelFileEventArgs e) {
            if(this.ModelFileUnloaded != null) {
                ModelFileUnloaded(this, e);
            }
        }

        void fileInfo_Loaded(object sender, ModelFileEventArgs e) {
            if(this.ModelFileLoaded != null) {
                ModelFileLoaded(this, e);
            }
        }

        public IModelFileHelper GetTempModelFileHelper() {
            Mockery mockery = new Mockery();
            return TestHelper.GetModelFileHelperMock(mockery);
        }

        public IModelDirectory GetModelDirectory() {
            if (modelDirectory == null) {
                modelDirectory = new ModelDirectory();
            }
            return modelDirectory;
        }

        public void CheckForDynamicStores() {
            
        }

        public void UnloadModel(IModelFileInfo modelFile) {}

        public List<Store> Stores { get { return new List<Store>(new Store[] {store}); } }
        public void LogMessage(string message) {
            
        }

        public event EventHandler<ModelFileEventArgs> ModelFileAdded;
        public event EventHandler<ModelFileEventArgs> ModelFileRemoved;
        public event EventHandler<ModelFileEventArgs> ModelFileLoaded;
        public event EventHandler<ModelFileEventArgs> ModelFileUnloaded;
        public event EventHandler<ModelFileEventArgs> ModelFileUpdated;
        private Store store = new Store();
    }
}